openGauss-tools-sql-translator
介绍
openGauss-tools-sql-translator是一个使用java编写的实现MySQL向openGauss语法转换的翻译器。其基于1.2.8版本Druid实现,利用Druid对AST的访问规则,继承MySQLOutPutVisitor并重载其visit方法,修改其对MySQL语句 AST的访问结果,最终输出openGauss语法的语句。
编译步骤
安装环境: java,maven,git
源数据库要求:MySQL 5.7。目的数据库要求:openGauss 3.0.0
打包命令:mvn package
MySQL与openGauss的兼容性说明
根据SQL语句在MySQL5.7官方文档和openGauss 3.0.0官方文档的差异对比,对各SQL语句进行翻译。下表展示SQL语句的翻译情况。
SQL语句
翻译情况
ALTER EVENT Statement、ALTER INSTANCE Statement、ALTER LOGFILE GROUP Statement、ALTER PROCEDURE Statement、CREATE EVENT Statement、CREATE LOGFILE GROUP Statement、DROP EVENT Statement、DROP LOGFILE GROUP Statement、DO Statement、HANDLER Statement、REPLACE Statement、Replication Statements、ITERATE Statement、Condition Handling、SET PASSWORD Statement、CHECK TABLE Statement、CHECKSUM TABLE Statement、OPTIMIZE TABLE Statement、REPAIR TABLE Statement、Plugin and Loadable Function Statements、SET NAMES Statement、SET CHARACTER Statement、SHOW Statements、BINLOG Statement、CACHE INDEX Statement、FLUSH Statement、KILL Statement、LOAD INDEX INTO CACHE Statement、DESCRIBE Statement、HELP Statement
openGauss不支持
SHUTDOWN Statement
Druid不支持
ALTER DATABASE Statement、ALTER FUNCTION Statement、ALTER SERVER Statement、ALTER TABLESPACE Statement、CREATE SERVER Statement、CREATE TABLESPACE Statement、DROP TRIGGER Statement、Prepared Statements、Cursors、ANALYZE TABLE Statement、RESET Statement、EXPLAIN Statement
无法兼容
ALTER TABLE Statement、ALTER VIEW Statement、CREATE DATABASE Statement、CREATE FUNCTION Statement、CREATE INDEX Statement、CREATE PROCEDURE Statements、CREATE TABLE Statement、CREATE TRIGGER Statement、CREATE VIEW Statement、DROP DATABASE Statement、DROP INDEX Statement、DROP TABLE Statement、DROP TABLESPACE Statement、DELETE Statement、INSERT Statement、SELECT Statement、Subqueries、UPDATE Statement、START TRANSACTION, COMMIT, and ROLLBACK Statements、SET TRANSACTION Statement、ALTER USER Statement、CREATE USER Statement、RENAME USER Statement、GRANT Statement、REVOKE Statement、SET param_name、USE Statement
部分支持
DROP FUNCTION Statement、DROP PROCEDUREand DROP FUNCTION Statements、DROP SERVER Statement、DROP VIEW Statement、RENAME TABLE Statement、TRUNCATE TABLE Statement、CALL Statement、BEGIN ... END Compound Statement、Statement Labels、DECLARE Statement、CASE Statement、IF Statement、LEAVE Statement、LOOP Statement、REPEAT Statement、RETURN Statement、WHILE Statement、DROP USER Statement
完全支持
openGauss不支持,表明会在日志中输出ERROR,由于该语句存在于需迁移的数据库对象中,所以该数据库对象迁移失败;
Druid不支持,表明该语句解析不成功,拥有该语句的数据库对象也迁移失败;
无法兼容,表明openGauss与MySQL一样支持该语句,但由于某些字段差异导致openGauss和MySQL之间无法转换。
完全支持指该语句的所有字段都可转化成openGauss的相应字段。
部分支持表明已尽可能地进行转换。若存在某些字段无法兼容但不影响整条语句的使用,则将该关键字进行注释处理;若某字段无法兼容且影响该语句的使用,则在日志中输出ERROR,说明该语句不能兼容的原因,拥有该语句的数据库对象迁移失败。比如在openGauss中CREATE TABLE Statement的AS query_expression不兼容MySQL;在openGauss中DELETE Statement不支持多表删除语法;在openGauss中SELECT Statement的select into字段仅支持变量是存储过程和函数参数或局部变量;在openGauss中UPDATE Statement不支持同时更新多表;GRANT statement、REVOKE statement语句若出现openGauss不支持赋予的privilege也会导致该语句无法迁移的情况;与PARTITION分区相关的语句也有可能因某些字段导致迁移失败等等,具体原因请查看日志。
以下对MySQL5.7版本的所有SQL语句具体的翻译情况进行说明。
13.1.1 ALTER DATABASE Statement
该语句openGauss和MySQL无法兼容,MySQL一定要有alter_option才能alter database,openGuass没有任何一个对应的alter_option
13.1.2 ALTER EVENT Statement
openGauss不存在该语句
13.1.3 ALTER FUNCTION Statement
无法支持,在openGauss中该字段的argtype是必须的,而Druid的alter function无法获取该字段。就算可以获取,MySQL的characteristic也只能翻译SECURITY字段
13.1.4 ALTER INSTANCE Statement
openGauss不存在该语句,同时Druid也没有该语句的解析
13.1.5 ALTER LOGFILE GROUP Statement
openGauss不存在该语句
13.1.6 ALTER PROCEDURE Statement
openGauss不存在该语句,同时Druid也没有该语句的解析
13.1.7 ALTER SERVER Statement
该语句openGauss和MySQL无法兼容,MySQL对于foreign data wrapper的支持与openGauss不同
13.1.8 ALTER TABLE Statement
openGauss不支持first、after字段、index_type、index_option、fulltext、spatial字段,注释掉
openGauss的add foreign key、add unique key 不支持index_name;druid不解析add unique key的constraint symbol
openGauss不支持algorithm、character set、 convert to character set、disable|enable keys、discard|import tablespace、drop index、drop primary key、drop foreign key、force、lock、order by、without|with validation
alter table 的 change和modify 关键字都翻译成先drop后add的形式
openGauss 不支持 rename index,支持重名表名字,但是需要分开成两个语句编写
13.1.9 ALTER TABLESPACE Statement
该语句openGauss和MySQL无法兼容。{ADD | DROP} DATAFILE 'file_name' 无法翻译,所以整个语句不支持翻译。
13.1.10 ALTER VIEW Statement
MySQL存在ALGORITHM、DEFINER、SQL SECURITY、 [WITH [CASCADED | LOCAL] CHECK OPTION]字段,openGauss不支持这些字段
13.1.11 CREATE DATABASE Statement
翻译成openGauss的CREATE SCHEMA,MySQL的create_option有 CHARACTER SET或 COLLATE字段,openGauss不兼容
13.1.12 CREATE EVENT Statement
openGauss不存在该语句
13.1.13 CREATE FUNCTION Statement
MySQL存在DEFINER、COMMENT、LANGUAGE SQL、SECURITY、CONTAINS SQL|NO SQL|READS SQL DATA|MODIFIES SQL DATA字段,openGauss不支持这些字段
Druid不支持解析CONTAINS SQL、NO SQL、READS SQL DATA、MODIFIES SQL DATA、SECURITY
把DETERMINISTIC翻译成openGauss的IMMUTABLE,当需要修改数据库时不能使用IMMUTABLE,此时用VOLATILE替换
13.1.14 CREATE INDEX Statement
openGauss不支持FULLTEXT | SPATIAL字段openGauss不存在该语句
openGauss的CONCURRENTLY表示以不阻塞DML的方式创建索引。MySQL有以下两种情况可以转换为openGauss的CONCURRENTLY,和MySQL的lock和algorithm字段相关:
lock=none
algorithm=inplace ,lock=default
其他情况的lock和algorithm字段,openGauss不支持
openGauss的key_part部分不支持(length),即为col_name指定长度
当using hash和asc|desc同时存在时会报错,因为openGauss的hash只能处理简单等值比较,using btree才能用asc|desc
openGauss不支持index_option(index_type除外)
13.1.15 CREATE LOGFILE GROUP Statement
openGauss不存在该语句
13.1.16 CREATE PROCEDURE Statements
MySQL存在DEFINER、COMMENT、LANGUAGE SQL、CONTAINS SQL|NO SQL|READS SQL DATA|MODIFIES SQL 字段,openGauss不支持该字段
Druid不支持解析NO SQL|READS SQL DATA|MODIFIES SQL字段druid不支持解析SECURITY字
把DETERMINISTIC翻译成openGauss的IMMUTABLE,当需要修改数据库时不能使用IMMUTABLE,此时用VOLATILE替换用IMMUTABLE替换MySQL的DETERMINISTI
13.1.17 CREATE SERVER Statement
该语句openGauss和MySQL无法兼容
13.1.18 CREATE TABLE Statement
数据类型: openGauss 不支持YEAR类型,ENUM和SET类型
MySQL的createde_finition中,openGauss不支持在表约束中创建INDEX | KEY、 {FULLTEXT | SPATIAL} [INDEX | KEY],将其翻译为CREATE TABLE和CREATE INDEX ON TABLE两个语句。{FULLTEXT | SPATIAL}省略。
MySQL的createde_finition中,openGauss不支持index_type、index_option、index_name。此外,Druid无法识别unique约束的约束名symbol
MySQL的column_definition中,openGauss不支持列约束中的COMMENT 、COLUMNFORMAT、STORAGE、GENERATED ALWAYS、VIRTUAL | STORED字段。AUTO_INCREMENT在openGauss中用bigserial达到整数自增的效果。COLLATE字段两者不兼容
MySQL的table_option中,openGauss只支持TABLESPACE(不支持[STORAGE {DISK | MEMORY}]字段)
openGauss 的create table as query expression 和 mysql有本质不同。MySQL在旧表上新加字段,openGauss是完全复制一样的表,无法转换
MySQL的like 默认源表保留新表的默认值表达式,存储引擎属性,check 约束,注释。所以在openGauss添加额外的表属性信息,like语句的like_option默认为INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING INDEXES INCLUDING STORAGE
partition:
openGauss不支持LINEAR字段
openGauss的PARTITION BY HASH的expr只翻译单个字段,openGauss 无法确保expr能够被正确解析;MySQL的PARTITION BY KEY需要翻译成 PARTITION BY HASH(column),column_list只支持单列;PARTITION BY RANGE的expr仅支持单列,多列则解析失败,column_list支持多列;PARTITION BY LIST的expr只翻译单个字段,无法确保expr能够被正确解析,column_list也仅支持单列
不支持PARTITIONS num、SUBPARTITION num字段
openGauss的partition name是必须的,所以MySQL要有partition_defition才可以翻译PARTITION
openGauss partition by 的某些数据类型和mysql有冲突,该需求比较复杂,先后置
Druid不解析SUBPARTITION BY KEY的ALGORITHM字段且openGauss不支持
在MySQL的partition_definition中,openGauss仅支持VALUES、TABLESPACE字段;engine、max_rows、min_rows将注释掉(druid把min_rows解析成了max_rows),comment、data directory、index directory将会引发语法错误,druid目前不解析
对于从句是VALUES LESS THAN的语法格式,openGauss范围分区策略的分区键最多支持4列
在MySQL的subpartition_definition中,openGauss仅支持TABLESPACE字段,engine、comment、data directory、index directory、max_rows、min_rows将注释掉
13.1.19 CREATE TABLESPACE Statement
该语句openGauss和MySQL无法兼容。ADD DATAFILE 'file_name'字段无法和openGauss的LOCATION 'directory'兼容。且durid代码存在无法解析add datafile的bug,已找到bug原因,考虑向durid仓库提出issue和pull_request修复
13.1.20 CREATE TRIGGER Statement
MySQL存在“[DEFINER = user]”字段,该DEFINER子句确定在触发器激活时检查访问权限时要使用的安全上下文。openGauss则不存在该字段
MySQL存在trigger_order字段,openGuass不存在
MySQL的trigger_body由一个有效的SQL例程语句或使用BEGIN AND编写的复合语句组成。openGauss通过EXECUTE PROCEDURE function_name来使用触发器函数,其中function_name 为用户定义的不带参数并返回类型为触发器的函数。所以需要把执行体转化成自定义函数,该函数名由UUID生成
13.1.21 CREATE VIEW Statement
MySQL存在ALGORITHM、DEFINER、SQL SECURITY、 [WITH [CASCADED | LOCAL] CHECK OPTION]字段,openGauss不支持这些字段
13.1.22 DROP DATABASE Statement
翻译成openGauss的DROP SCHEMA语句
13.1.23 DROP EVENT Statement
openGauss不存在该语句
13.1.24 DROP FUNCTION Statement
无需翻译,完全支持
13.1.25 DROP INDEX Statement
openGauss不支持指定tbl_name
openGauss的CONCURRENTLY表示以不阻塞DML的方式创建索引
MySQL有以下两种情况可以转换为openGauss的CONCURRENTLY,和MySQL的lock和algorithm字段相关:
lock=none
algorithm=inplace ,lock=default
其他情况的lock和algorithm字段,openGauss不支持
13.1.26 DROP LOGFILE GROUP Statement
openGauss不存在该语句
13.1.27 DROP PROCEDURE and DROP FUNCTION Statements
无需翻译,完全支持
13.1.28 DROP SERVER Statement
无需翻译,完全支持
13.1.29 DROP TABLE Statement
MySQL可以拥有TEMPORARY字段,仅删除TEMPORARY表,openGauss不支持,目前做法是直接把TEMPORARY注释掉
13.1.30 DROP TABLESPACE Statement
ENGINE字段不支持该语句在openGauss中需要有ON table_name,而druid的drop trigger无法获取该字
13.1.31 DROP TRIGGER Statement
该语句openGauss和MySQL无法兼容。opengauss的drop trigger需要ON table_name 而druid内该语句没有该字段定义
13.1.32 DROP VIEW Statement
无需翻译,完全支持
13.1.33 RENAME TABLE Statement
openGauss通过ALTER TABLE重名名表,可以用ALTER TABLE直接翻译
13.1.34 TRUNCATE TABLE Statement
无需翻译,完全支持
13.2.1 CALL Statement
无需翻译,完全支持
13.2.2 DELETE Statement
low_priority、quick、ignore关键词不支持
order by、limit不支持
openGauss不支持partition_name有多个
openGauss不支持多表删除语法
13.2.3 DO Statement
openGauss不存在该语句,且Druid不支持解析此语句
13.2.4 HANDLER Statement
openGauss不存在该语句
13.2.5 INSERT Statement
不支持LOWPRIORITY | DELAYED | HIGHPRIORITY、IGNORE字段
openGauss不支持partition_name有多个
13.2.6 LOAD DATA Statement
无需翻译,存储过程体、函数体不支持该语句
13.2.7 LOAD XML Statement
无需翻译,存储过程体、函数体不支持该语句
13.2.8 REPLACE Statement
openGauss不存在该语句,与其同义的INSERT IGNORE也不存在
13.2.9 SELECT Statement
openGauss不支持DISTINCTROW、HIGH_PRIORITY、STRAIGHT_JOIN、SQL_SMALL_RESULT、SQL_BIG_RESULT、SQL_BUFFER_RESULT、SQL_CACHE、 SQL_NO_CACHE、 SQL_CALC_FOUND_ROWS、PROCEDURE procedurename(argumentlist)字段
Druid不解析PROCEDURE procedurename(argumentlist)字段,
druid不解析PARTITION partition_list字段
MySQL的SELECT... INTO var_list,openGauss仅支持变量是存储过程或函数参数,或存储过程或函数局部变量,不支持用户定义的变量(@开头的)。MySQL的SELECT ... INTO OUTFILE、SELECT ... INTO DUMPFILE,openGauss也不支持
druid不解析PARTITION partition_list字段、SELECT ... INTO DUMPFILE
在字段table_references中,MySQL 支持 INNER、CROSS、LEFT [OUTER]、RIGHT [OUTER]、NATURAL、STRAIGHT_JOIN六种join类型,openGauss 不支持 STRAIGHT_JOIN 这种类型,STRAIGHT_JOIN 功能同 JOIN 类似,使用 JOIN 替代
openGauss的存储过程不能用select返回数据
13.2.10 Subqueries
无需翻译,完全支持
13.2.11 UPDATE Statement
openGauss不支持LOW_PRIORITY、IGNORE、ORDER BY ...、LIMIT rowcount字段
tablereference字段在openGauss中只支持一个表名tablename
13.3.1 START TRANSACTION, COMMIT, and ROLLBACK Statements 13.3.6 SET TRANSACTION Statement
在STRAT TRANSACTION语句中,openGuass不支持WITH CONSISTENT SNAPSHOT字段
在BEGIN、COMMIT、ROLLBACK语句中,openGauss不支持AND [NO] CHAIN 、[NO] RELEASE字段
在SET TRANSACTION语句中,openGuass不支持GLOBAL、READ UNCOMMITTED字段。MySQL字段SESSION在openGauss中翻译为SESSION CHARACTERISTICS AS
目前的sql-translator不支持在对象中使用(如存储过程)COMMIT、ROLLBACK语句,解析出错
13.4 Replication Statements
openGauss不存在该语句
13.5 Prepared Statements
该语句openGauss和MySQL无法兼容。
MySQL通过使用字符串文字来提供语句的文本或将语句文本作为用户变量提供来创建PREPARE语句,两种方式openGauss都不支持,openGauss的PREPARE语句直接指明参数类型
MySQL的EXECUTE语句也需要用到用户变量,openGauss不支持
13.6.1 BEGIN ... END Compound Statement
完全支持
13.6.2 Statement Labels
Druid解析label时,需要使用"label: ",即冒号后需要有空格才能解析
13.6.3 DECLARE Statement
完全支持
13.6.5 Flow Control Statements
其中openGauss不支持ITERATE
openGauss不存在REPEAT语句,用LOOP语句替换
druid不支持解析case语句的第二种语法,因此无法转换
CASE、IF、LEAVE、LOOP、REPEAT、RETURN、WHILE完全支持
13.6.6 Cursors
无法兼容。MySQL的FETCH有INTO var_name字段,openGauss没有,无法提取的列存储在命名变量中
13.6.7 Condition Handling
openGauss不存在该语句
13.7.1.1 ALTER USER Statement
druid不解析REQUIRE、WITH resourceoption、lockoption字段,其中lock_option字段openGauss中存在
openGauss不支持IF EXISTS、user()、auth_plugin字段
openGauss的Account names不需要单引号,且没有hostname的部分,目前解决方法是截取username的部分并去除双引号
openGauss的password_option字段仅支持 PASSWORD EXPIRE
13.7.1.2 CREATE USER Statement
druid不解析REQUIRE、WITH resourceoption、passwordoption、lock_option字段且openGauss也不支持
openGauss不支持IF NOT EXISTS、auth_plugin字段
openGauss的Account names不需要单引号,且没有hostname的部分,目前解决方法是截取username的部分并去除双引号
13.7.1.3 DROP USER Statement
无需翻译,完全支持
13.7.1.4 GRANT Statement
opengauss无resource_option
opengauss无require子句
MySQL所授予的权限为全局、数据库、表和例程级别。opengauss不支持赋予权限给全局级别(.)、默认数据库(*)
MySQL若只是赋予CREATE权限给数据库级别(db_name.),则可直接对应到openGauss的SCHEMA;若赋予权限ALTER、DELETE、INDEX、INSERT、REFERENCES、SELECT、UPDATE给数据库级别(db_name.),其实是对所有的表赋权,翻译到openGauss应该是 ALL TABLES IN SCHEMA schema_name;若赋予权限EXECUTE、ALTER ROUTINE给数据库级别(db_name.),其实是对所有的函数和存储过程赋权,翻译到openGauss应该是ALL FUNCTIONS\PROCEDURE IN SCHEMA schema_name;MySQL若赋予权限ALL[PRIVILEAGE]、DROP给数据库级别(db_name.),则翻译为不仅对openGauss的schema赋权还有对其下的所有表赋权。其余赋予给数据库级别(db_name.*)的权限CREATE ROUNTION、CREATE TEMPORARY TABLES、CREATE VIEW、EVENT、LOCK TABLES、SHOW VIEW、TRIGGER,openGauss不支持
MySQL若赋予权限给特定的FUNCTION或PROCEDURE,openGauss不能兼容,因为opengauss的FUNCTION或PROCEDURE都必须带有参数类型
MySQL如果赋予权限给特定的TABLE(db_name.tbl_name、tbl_name),其中权限ALTER、DELETE、DROP、INSERT、REFERENCES、SELECT、UPDATE、INDEX、GRANT OPTION、ALL可以成功翻译openGauss对应的特定TABLE的权限,并且需要把表所属模式的USAGE权限同时赋予该用户。其余权限CREATE、CREATE VIEW、LOCK TABLES、SHOW VIEW、TRIGGER、USAGE,openGauss不支持
opengauss的用户不带有hostname,mysql转换会丢失信息
13.7.1.5 RENAME USER Statement
通过ALTER USER改变用户名
druid无法解析该语句多个用户同时重命名
13.7.1.6 REVOKE Statement
见13.7.1.4 GRANT Statement
13.7.1.7 SET PASSWORD Statement
openGauss不存在该语句
13.7.2 Table Maintenance Statements
13.7.2.1 ANALYZE TABLE Statement无法兼容。其中MySQL的ANALYZEA TABLE语句与openGauss不兼容。openGuass的ANALYZE非临时表不能在一个匿名块、事务块、函数或存储过程内被执行。而MySQL没有此限制。
openGauss不存在13.7.2.2 CHECK TABLE Statement、13.7.2.3 CHECKSUM TABLE Statement、13.7.2.4 OPTIMIZE TABLE Statement、13.7.2.5 REPAIR TABLE Statement
13.7.3 Plugin and Loadable Function Statements
openGauss不存在该语句
13.7.4 SET Statements
13.7.4.1 SET Syntax for Variable Assignment openGauss不支持user_var_name、local_var_name、 system_var_name
openGauss不存在13.7.4.2 SET CHARACTER SET Statement、13.7.4.3 SET NAMES Statement
13.7.5 SHOW Statements
openGauss不存在该语句
13.7.6 Other Administrative Statements
openGauss不存在13.7.6.1 BINLOG Statement、13.7.6.2 CACHE INDEX Statement、13.7.6.3 FLUSH Statement、13.7.6.4 KILL Statement、13.7.6.5 LOAD INDEX INTO CACHE Statement
13.7.6.6 RESET Statement无法兼容。openGauss不支持MySQL的reset_option
13.8 Utility Statements
openGauss不存在13.8.1 DESCRIBE Statement、13.8.3 HELP Statement
13.8.2 EXPLAIN Statement目前不翻译EXPLAIN语句,因为MySQL与openGauss的EXPLAIN输出不一样
注意事项
对象迁移时所有包含大小写的字段名(包括表名、数据库名、列名、别名、用户名、变量名、索引名、分区名等)保持大小写迁移。当在openGauss访问这些字段时,需要使用双引号才能识别该字段。
|